package com.codemonkey.lq.qd.facotry.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import com.codemonkey.lq.qd.utils.StringHelper;

public abstract class AbstractServiceDefinition implements ServiceDefinition {

	private String id;

	/**
	 * Action中的外部来源的参数
	 */
	private Set<String> externalParams = new HashSet<String>(5);

	private Map<String, ActionDefinition> actionContainer = new LinkedHashMap<String, ActionDefinition>(
			10);
	private List<FlowDefinition> flows = new ArrayList<FlowDefinition>(10);

	//************************************************************************
	//   Implement  ServiceDefinition   Interface
	//************************************************************************
	@Override
	public boolean addAction(ActionDefinition action) {
		String key = dealWithActionName(action.getName());
		if (actionContainer.containsKey(key)) {
			String errorInfo = String.format(
					"this action which named '%s' has been added to Serivce '%s' ", key, id);
			throw new IllegalArgumentException(errorInfo);
		}

		// 抽取本action中的参数
		Set<String> actionParams = extractActionParams(action);
		externalParams.addAll(actionParams);

		actionContainer.put(key, action);

		return true;
	}

	private Set<String> extractActionParams(ActionDefinition ad) {
		Set<String> params = new HashSet<String>();

		String parameter = ad.getParameter();
		if (StringHelper.isEmpty(parameter)) {
			return Collections.emptySet();
		}

		String[] arr = parameter.split("\\+");
		for (String str : arr) {
			params.add(str);
		}

		return params;

	}

	@Override
	public Set<String> getActionParams() {
		return Collections.unmodifiableSet(externalParams);
	};

	@Override
	public boolean removeAction(ActionDefinition action) {
		String actionName = dealWithActionName(action.getName());
		actionContainer.remove(actionName);
		return true;
	}

	@Override
	public ActionDefinition getSpecialAction(String actionName) {
		actionName = dealWithActionName(actionName);
		return actionContainer.get(actionName);
	}

	@Override
	public Collection<ActionDefinition> getActionGroup() {
		return Collections.unmodifiableCollection(actionContainer.values());
	}

	@Override
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	private String dealWithActionName(String actionName) {
		return actionName.toUpperCase(Locale.ENGLISH);
	}

	//************************************************************************
	//   Implement  FlowGraph   Interface
	//************************************************************************
	@Override
	public boolean addFlow(FlowDefinition flow) {
		if (flows.contains(flow)) {
			String errorInfo = String.format("this flow '%s' has been added to Serivce '%s' ", flow
					.toString(), id);
			throw new IllegalArgumentException(errorInfo);
		}
		return flows.add(flow);
	}

	@Override
	public boolean removeFlow(FlowDefinition flow) {
		return flows.remove(flow);
	}

	@Override
	public Collection<FlowDefinition> getFlowGroup() {
		return Collections.unmodifiableCollection(flows);
	}
}
